/**
 * 
 */
package com.magnusart.scrumify.dao;

import static org.junit.Assume.assumeNotNull;
import static org.junit.Assume.assumeTrue;

import java.io.BufferedReader;
import java.io.FileReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

import com.magnusart.scrumify.dao.DAOFactory;
import com.magnusart.scrumify.dao.HsqlDbDAOFactory;

/**
 * @author magnus
 *
 */
public class DBTestUtil
{
	
	private static Connection c;

	public static void setUpTempDatabase() throws Exception {
		try {
			Class.forName( "org.hsqldb.jdbcDriver" );
		} catch ( Exception e ) {
			System.out.println( "ERROR: failed to load HSQLDB JDBC driver." );
			e.printStackTrace();
		}

		// Get a connection
		c = DriverManager.getConnection( "jdbc:hsqldb:mem:testdb", "sa", "" );

		setUpDatabase();
	}
	
	public static void setUpDatabase() throws Exception {
		Statement st;
		int i;
		
		// First set up the database for DbDeploy
		String exp = readFileIntoStringStripShutdown( "/db/scripts/createSchemaVersionTable.hsql.sql" );
		
		assumeNotNull( exp );
		
		st = c.createStatement();
		
		i = st.executeUpdate( exp ); // run the query
		
		assumeTrue( i != -1 );
		
		// Then do the regular stuff
		exp = readFileIntoStringStripShutdown( "/db/scripts/all-deltas.sql"  );
		
		assumeNotNull( exp );
		try {
			i = st.executeUpdate( exp ); // run the query
		} catch ( Exception e ) {
			e.printStackTrace();
			throw e;
		}
		assumeTrue( i != -1 );
		
		// Insert test data into database
		exp = readFileIntoString( "/db/scripts/insert_test_data.sql" );
		
		assumeNotNull( exp );
		
		try {
			i = st.executeUpdate( exp );
		} catch( Exception e ) {
			e.printStackTrace();
			throw e;
		}
		assumeTrue( i != -1 );
		
		
		st.close();
	}

	public static void closeConn() throws Exception {
		Statement st = c.createStatement();

		// db writes out to files and performs clean shuts down
		// otherwise there will be an unclean shutdown
		// when program ends
		st.execute( "SHUTDOWN" );
		st.close();
		c.close(); // if there are no other open connection
	}
	
	
	public static DAOFactory generateFactory( ) {
		return DAOFactory.getDAOFactory();
	}
	
	/**
	 * Used to read a file into a string
	 * @param relativePath
	 * @return
	 * @throws Exception
	 */
	public static String readFileIntoString( String relativePath ) throws Exception{
		StringBuffer sb = new StringBuffer( 1000 );
		FileReader fr = new FileReader( System.getProperty( "user.dir" ) + relativePath );
		BufferedReader br = new BufferedReader( fr );
		char buf[] = new char[1024];
		int numRead = 0;
		
		while( (numRead=br.read(buf)) != -1 ) {
			sb.append( buf, 0, numRead );
		}
		
		fr.close();
		br.close();
		
		return sb.toString();
	}
	
	/**
	 * Is used to strip commit from the setup sql commands.
	 * @param relativePath
	 * @return
	 * @throws Exception
	 */
	public static String readFileIntoStringStripShutdown( String relativePath ) throws Exception {
		BufferedReader in = new BufferedReader( new FileReader( System.getProperty( "user.dir" ) + relativePath ) );
		
		String data = "", line;
		while( ( line = in.readLine() ) != null ) {
			if( !line.startsWith( "SHUTDOWN" )) {
				data += line + "\n";
			}
		}
		
		in.close();
		
		return data;
	}
	
	
	/**
	 * Used to hook into the database connection
	 * @author magnus
	 *
	 */
	public static class SeamedHsqlDbDAOFactory extends HsqlDbDAOFactory
	{

		@Override
		protected Connection getConnection() {
			return c;
		}

		@Override
		protected void closeConnection( ) {
			//Do nothing since we need the connection to be open to the in memory non persistent database
		}
	}

}
